package com.blog.quartz;
import com.blog.Utils.RedisKeyUtil;
import com.blog.Utils.SpringContextJobUtil;
import com.blog.bean.domain.DiscussPost;
import com.blog.mapper.Search.DiscussPostRepoistory;
import com.blog.service.DiscussPostService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

/**
 * @author 任浩
 * @version 1.0
 */

@Slf4j
//@Component
public class ScoreRefreshJob implements Job {

    @Resource
    private RedisTemplate redisTemplate;
    @Autowired
    private DiscussPostService discussPostService;
    @Autowired
    private DiscussPostRepoistory discussPostRepoistory;  //这是对es进行操作的类。

    private static LocalDateTime createTime;

    private static final int OFFSET = 8 * 60 * 60;


    static {  //静态代码块，只加载一次
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        createTime = LocalDate.parse("2023-11-19",dateTimeFormatter).atStartOfDay();
    }

    /**
     * 这是线程池进行处理的业务。
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //从redis中取到所有的需要进行更新热度分数的帖子id。
        String scoreKey = RedisKeyUtil.scoreInit();
        log.info("redistmplate：{}",redisTemplate);
        SetOperations setOperations = redisTemplate.opsForSet();

        if( setOperations.size(scoreKey) == 0){
            log.info("没有新的帖子要我们更新热度分数");
            return;
        }

        log.info("要进行更新的热度的帖子的数量为：" + setOperations.size(scoreKey));
        while (setOperations.size(scoreKey) != 0){
            Integer pop = (Integer)setOperations.pop(scoreKey);
            //对每一个帖子进行操作。
            //通过帖子id，得到帖子的实体对象
            DiscussPost discussPost = new DiscussPost();
            discussPost.setId(pop);
            discussPostService = (DiscussPostService)SpringContextJobUtil.getBean("discussPostServiceImpl");
            discussPost = discussPostService.queryPostByPostId(discussPost);
            //判断帖子是否加精
            boolean wonderful = false;
            if(discussPost.getStatus() == 1){
                wonderful = true;
            }
            //得到帖子的评论数量
            Integer commentCount = discussPost.getCommentCount();
            //得到帖子的点赞数量
            String likeKey = RedisKeyUtil.init(discussPost.getId().toString());
            Long likeCount = redisTemplate.opsForSet().size(likeKey);
            //通过公式计算出热度分数。
            //公式为： score = log(精华分+评论数*10 + 点赞数**2 + 收藏数****2) + (发布时间-牛客纪元)

            Integer wonderfulScore = 0;
            if(wonderful == true){
                wonderfulScore = 100; //精华分的底分为100
            }
            //得到时间。
            LocalDateTime postCreateTime = discussPost.getCreateTime();
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String format = postCreateTime.format(dateTimeFormatter);
            LocalDateTime postDateTime = LocalDate.parse(format, dateTimeFormatter).atStartOfDay();

            //进行计算得到时间差的毫秒数
            long postMillis = postDateTime.toInstant(ZoneOffset.ofTotalSeconds(OFFSET)).toEpochMilli();
            long creatMillis = createTime.toInstant(ZoneOffset.ofTotalSeconds(OFFSET)).toEpochMilli();

            Long score = (wonderfulScore + commentCount * 2 + likeCount *2) + (postMillis-creatMillis);
            double v = Math.log10(score);
            //计算得到的分数为：
            System.out.println(v);

            //将分数保存到数据库中。
            discussPost.setScore(v);
            discussPostService.updateScore(discussPost);
            //然后将分数更新到es中，把es中的数据进行更新
            discussPostRepoistory.save(discussPost);
        }
        log.info("更新热度的帖子结束");
    }
}
